﻿using System;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using PodpisyElektorniczne.Classes;
using PodpisyElektorniczne.Interfaces;

namespace PodpisyElektorniczne
{
    public partial class frmSettings : Form
    {
        private KeyPreferences _pref;
        
        public TextBox MainForm;
        private SchemaSetts ss;
        private readonly string _keyPath;

        public frmSettings()
        {
            InitializeComponent();
            _pref = new KeyPreferences();
            _pref = KeyPreferences.ObjDeserializer();
            _keyPath = string.Format("{0}\\{1}\\{2}", Settings.MainDirectoryPath, Form1.Log.Usser.Login,
                                     Settings.KeyPairFilename);
            ss = new SchemaSetts(Program.Log.Usser.Login);
            lbl_secretsGen.Text = (ss = 
                ss.XmlDeserializeSchemaProperties()) == null ?  @"No" : (ss.SecretR != -1 ? @"Yes" :  @"No");
                
            
            lbl_genSettings.Text = ss == null ? @"No" : (ss.GeneratorG != -1 ? @"Yes" : @"No");
            var kfactory = new UserKeyFactory();
            if(File.Exists(_keyPath))
                kfactory.Deserialize(_keyPath);
            lbl_KeyGenerated.Text =  kfactory.KeyPair.Y != -1 ? @"Yes" : @"No";
            ud_NoRing.Value = _pref.NoMembers;
            ud_GroupZp.Value = _pref.LengthOrderZp;
            ud_GroupZq.Value = _pref.LengthOrderZq;
            ud_TrialsPrimes.Value = _pref.NoTrials;
            switch(_pref.IsRandom)
            {
                case true:
                    ud_NoRing.Enabled = !_pref.IsRandom;
                    chb_IsRandom.Checked = _pref.IsRandom;
                    break;
                default:
                    ud_NoRing.Enabled = true;
                    break;
            }
        }

    
        private void btn_SaveSettings_Click(object sender, EventArgs e)
        {
            MainForm.Text = string.Format("{0}{1}", @"Storing settings, wait...", Environment.NewLine) + MainForm.Text;
            try
            {
                var g = _pref;

                if (String.CompareOrdinal(lbl_KeyGenerated.Text, "No") == 0)
                {
                    g.IsGenerated = 0;
                }
                else
                {
                    g.IsGenerated = 1;
                    txt_PublicKey.Text = _keyPath;
                    txt_PrivateKeyPath.Text = _keyPath;
                }
                
                _pref.NoMembers = (int)ud_NoRing.Value;
                
                g.LengthOrderZp = Int32.Parse(ud_GroupZp.Value.ToString());
                g.LengthOrderZq = Int32.Parse(ud_GroupZq.Value.ToString());
                g.NoMembers = (int) ud_NoRing.Value;
                g.NoTrials = (int) ud_TrialsPrimes.Value;
                Form1.KeyPrefs = g;
                KeyPreferences.ObjSerialization(g);
                MainForm.Text = string.Format("{0}{1}", @"Settings has been saved. Window closed.", Environment.NewLine) + MainForm.Text;
                Close();
                Dispose();
                
            }
            catch (Exception ex)
            {
                lbl_genSettings.Text = @"No";
                MainForm.Text = string.Format("{0}{1}", @"There was a problem with storing settings. Try again.", Environment.NewLine) + MainForm.Text;
                MessageBox.Show(@"There was a problem with storing settings. Try again. \n"+ex.Message, @"Error", MessageBoxButtons.OK);
            }
        }
      
        //public static T XmlDeseriali<T>(string filename)
        //{
        //    try
        //    {   
        //        if(string.IsNullOrEmpty(filename))
        //        {
        //            return default(T);
        //        }
        //        using (var store = IsolatedStorageFile.GetMachineStoreForAssembly())
        //        {
        //            if (store.FileExists(filename))
        //            {

        //                using (var stream = store.OpenFile(filename, FileMode.Open, FileAccess.Read))
        //                using (var freader = XmlReader.Create(stream))
        //                {
        //                    //if (typeof(T).Name == "KeyPreferences") Settings._isPath = IsolatedStorageFile.GetUserStoreForAssembly().;//Position.ToString();)
        //                    return (T) new XmlSerializer(typeof (T)).Deserialize(freader);
        //                }
        //            }
        //            return default(T);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
                
        //        MessageBox.Show(@"There is a problem with loading preferences. Try again." + ex.Message, @"Error", MessageBoxButtons.OK);
        //        return default(T);
        //    }
        //}
        

        private void frmSettings_Load(object sender, EventArgs e)
        {
            try
            {
                var tmp = Form1.KeyPrefs;

                //if (null != tmp || -1 != tmp.IsGenerated)
                //{
                    //if(File.Exists(_keyPath))
                    //{
                    //    txt_PublicKey.Text = _keyPath;
                    //    txt_PrivateKeyPath.Text = _keyPath;
                    //}
                    
                    //if (File.Exists(_keyPath))
                    //    lbl_KeyGenerated.Text = @"Yes";
                    //if (ss != null)
                    //{
                    //    if (ss.DashedGeneratorG != -1 || ss.GeneratorG != -1 ||
                    //        ss.OrderP != -1 || ss.SubOrderQ != -1)
                    //    {
                    //        lbl_genSettings.Text = @"Yes";
                    //        //btn_schemaSettings.Enabled = false;
                    //        if (ss.SecretR != -1 || ss.SecretRj != -1)
                    //            lbl_secretsGen.Text = @"Yes";
                    //    }
                    //}

                    //szukam wszystkich możliwych kluczy publicznych
                    var possibleDir = Directory.GetDirectories(Settings.MainDirectoryPath);
                    ud_NoRing.Maximum = possibleDir.Count(i => File.Exists(string.Format("{0}\\{1}", i, Settings.KeyPairFilename)));
                    //ud_NoRing.Value = tmp.NoMembers;
                    

                    //if (tmp.LengthOrderZp != 0)
                    //    ud_GroupZp.Value = tmp.LengthOrderZp;
                    //else
                    //    ud_GroupZp.Value = 16;

                    //if (tmp.LengthOrderZq != 0)
                    //    ud_GroupZq.Value = tmp.LengthOrderZq;
                    //else
                    //    ud_GroupZq.Value = 16;

                    //ud_TrialsPrimes.Value = tmp.NoTrials;
                    
                    //txt_PrivateKeyPath.Text = File.Exists(_keyPath) ? _keyPath : "";
                    //txt_PublicKey.Text = File.Exists(_keyPath) ? _keyPath : "";
                    MainForm.Text = string.Format("{0}{1}", @"General settings has been loaded.", Environment.NewLine) +
                                    MainForm.Text;
                //}
                //else
                //{
                //    MessageBox.Show(
                //        @"There is no settings for signature schema, to proceed you need to generate settings !",
                //        @"Warning",
                //        MessageBoxButtons.OK);
                //}
            }catch(Exception)
            {
                throw;
            }

        }

        private void btn_CancelSettings_Click(object sender, EventArgs e)
        {
            this.Close();
            this.Dispose();
            MainForm.Text = string.Format("{0}{1}", @"Preferences closed", Environment.NewLine) + MainForm.Text;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MainForm.Text = string.Format("{0}{1}", @"Generating keys...", Environment.NewLine) + MainForm.Text;
            if (ss != null || -1 != ss.SubOrderQ)
            {
                //TO DO: CreateRSAKey();
                //TO DO: Form1.RSAKeys.GenerateRsaKeys();

                var kFactory = new UserKeyFactory();
                kFactory.KeyPair.GenerateKeyPair(ss.SubOrderQ, ss.GeneratorG);
                
                //var RSAKeysProps = new RsaKeysProperties(_pref.LengthOrderZq, _pref.NoTials);
                //RSAKeysProps.GenerateRsaPublicKey(_pref.LengthOrderZq, _pref.NoTials);
                //RSAKeysProps.GenerateRsaPrivateKey();
                //RSAKeysProps.PubKey.E = BI.ModPow(ss.GeneratorG, RSAKeysProps.PrivKey.D, ss.SubOrderQ);
                if (kFactory.Serialize(_keyPath))
                {    
                    
                    MessageBox.Show(@"Keys saved successfully !", @"RSA Result", MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);

                    lbl_KeyGenerated.Text = @"Yes";
                    MainForm.Text = string.Format("{0}{1}", @"Keys generated and stored successfuly.", Environment.NewLine) + MainForm.Text;
                }
                else
                {
                    MessageBox.Show(@"Keys weren't save!", @"RSA Result", MessageBoxButtons.OK,
                                    MessageBoxIcon.Warning);
                }
                
                
            }
            else
            {
                lbl_KeyGenerated.Text = @"No";
                MainForm.Text = string.Format("{0}{1}", @"Try to generate settings, if this is a first run on this computer.", Environment.NewLine) + MainForm.Text;
                MessageBox.Show(@"Try to generate settings, if this is a first run on this computer.", @"Warning",MessageBoxButtons.OK);
            }
        }

        
        private void btn_schemaSettings_Click(object sender, EventArgs e)
        {
            MainForm.Text = string.Format("{0}{1}", @"Generating settings. It may take some time. I hope you set short bit lenght for group orders!!", Environment.NewLine) + MainForm.Text;
            var sts = (new SchemaSetts(Program.Log.Usser.Login)).XmlDeserializeSchemaProperties() ?? new SchemaSetts(Program.Log.Usser.Login);
            if (sts.GenerateSchemaSettings())
            {
                if (sts.XmlSerializeSchemaProperties())
                {
                    lbl_genSettings.Text = @"Yes";
                    ss = sts;
                    //Form1.RSAKeys.Sts = set;
                    MainForm.Text =
                        string.Format("{0}{1}", @"Generating settings has finished successfuly.", Environment.NewLine) +
                        MainForm.Text;
                }
                else
                {
                    MainForm.Text =
                        string.Format("{0}{1}", @"Generating settings hasn't finished correctly. Problem with storing Key Setts.", Environment.NewLine) +
                        MainForm.Text;
                }
            }
        }
        
        
        //generuję sekrety dla danego user'a: R oraz Rj
        private void button1_Click_1(object sender, EventArgs e)
        {
            try
            {
                var set = (new SchemaSetts(Form1.Log.Usser.Login)).XmlDeserializeSchemaProperties();
                if(set == null) throw new Exception(@"There is no data required. Generate first schema settings.");
                set.GenerateSecrets();
                
                if(set.XmlSerializeSchemaProperties())
                {
                    lbl_secretsGen.Text = @"Yes";
                    
                    MainForm.Text = @"Secrets has been generated for this user." + MainForm.Text;
                }
            }
            catch(Exception)
            {
                lbl_secretsGen.Text = @"No";
                MainForm.Text = @"No secrets has been generated. Try again." + MainForm.Text;
                MessageBox.Show(@"No secrets has been generated. Generate settings and try again.", @"Error", MessageBoxButtons.OK);
            }
        }

        private void ud_TrialsPrimes_ValueChanged(object sender, EventArgs e)
        {
            _pref.NoTrials = (int) ud_TrialsPrimes.Value;
        }

        private void ud_GroupZq_ValueChanged(object sender, EventArgs e)
        {
            _pref.LengthOrderZq =(int)ud_GroupZq.Value;
        }

        private void ud_GroupZp_ValueChanged(object sender, EventArgs e)
        {
            _pref.LengthOrderZp = (int) ud_GroupZp.Value;
        }

        private void ud_NoRing_ValueChanged(object sender, EventArgs e)
        {
            _pref.NoMembers = (int) ud_NoRing.Value;
        }

        private void chb_IsRandom_CheckedChanged(object sender, EventArgs e)
        {
            var obj = (CheckBox) sender;

            switch (obj.Checked)
            {
                case true:
                    ud_NoRing.Enabled = !obj.Checked;
                    break;
                default:
                    ud_NoRing.Enabled = true;
                    break;
            }
            _pref.IsRandom = obj.Checked;
        }

        
    }
}
